﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LM.InterfacesFabricas.Interfaces.Repositorios;
using LM.Negocio.Objetos;
using LM.InterfacesFabricas.Basicos.Enumeradores;

namespace LM.Negocio.Validadores
{
    public class ValidadorDeEndereco : ValidadorAbastrato
    {
        private Endereco _objetoValidado;

        private IRepositorioDeConsultaDeObjetos<Endereco> _repositorioDeEndereco;

        public ValidadorDeEndereco(IRepositorioDeConsultaDeObjetos<Endereco> repositorioDeEndereco)
        {
            if (repositorioDeEndereco == null)
            {
                throw new ArgumentNullException("repositorioDeEndereco");
            }

            _repositorioDeEndereco = repositorioDeEndereco;
        }
        public ValidadorDeEndereco() { }

        public void ValideCadastro(Endereco endereco)
        {
            if (endereco == null)
            {
                throw new ArgumentException("Endereco");
            }

            _objetoValidado = endereco;
            base.LimpeInconsistencias();

            ValideCodigoNaoInformado();
            ValideLogradouroNaoInformado();
            ValideLoteNaoInformado();
            ValideQuadraNaoInformada();
            ValideBairroNaoInformado();
            ValideCidadeNaoInformado();
            ValideUfNaoInformado();

            ValideEnderecoJaCadastrado();

            base.GarantaSucesso();
        }

        public void ValideAtualizacao(Endereco endereco)
        {
            if (endereco == null)
            {
                throw new ArgumentException("Endereco");
            }

            _objetoValidado = endereco;
            base.LimpeInconsistencias();

            ValideCodigoNaoInformado();
            ValideLogradouroNaoInformado();
            ValideLoteNaoInformado();
            ValideQuadraNaoInformada();
            ValideBairroNaoInformado();
            ValideCidadeNaoInformado();
            ValideUfNaoInformado();

            ValideEnderecoNaoCadastrado();

            base.GarantaSucesso();
        }

        public void ValideExclusao(Endereco endereco)
        {
            if (endereco == null)
            {
                throw new ArgumentException("Endereco");
            }

            _objetoValidado = endereco;
            base.LimpeInconsistencias();

            ValideEnderecoNaoCadastrado();

            base.GarantaSucesso();
        }

        private void ValideCodigoNaoInformado()
        {
            if (_objetoValidado.Codigo == 0)
            {
                AdicioneInconsistencia("Código não informado.");
            }
        }

        private void ValideLogradouroNaoInformado()
        {
            if (String.IsNullOrWhiteSpace(_objetoValidado.Logradouro))
            {
                AdicioneInconsistencia("Logradouro não informado.");
            }
        }

        private void ValideLoteNaoInformado()
        {
            if (string.IsNullOrWhiteSpace(_objetoValidado.Logradouro)) 
            {
                AdicioneInconsistencia("Lote não Informado.");
            }
        }
        
        private void ValideQuadraNaoInformada()
        {
            if (string.IsNullOrWhiteSpace(_objetoValidado.Quadra))
            {
                AdicioneInconsistencia("Quadra não informada.");
            }
        }

        private void ValideBairroNaoInformado() 
        {
            if (string.IsNullOrWhiteSpace(_objetoValidado.Bairro)) 
            {
                AdicioneInconsistencia("Bairro não informado.");
            }
        }

        private void ValideCidadeNaoInformado()
        {
            if (string.IsNullOrWhiteSpace(_objetoValidado.Cidade))
            {
                AdicioneInconsistencia("Cidade não informado.");
            }
        }

        private void ValideUfNaoInformado()
        {
            if (!Enum.IsDefined(typeof(EnumUnidadeFederativa), _objetoValidado.Uf))
            {
                AdicioneInconsistencia("UF da cidade do endereço não informado.");
            }
        }

        private bool EnderecoJaCadastrado()
        {
            return _repositorioDeEndereco.Consulte(m => m.Codigo == _objetoValidado.Codigo).Any();
        }

        public bool EnderecoJaCadastrado(Endereco endereco)
        {
            return _repositorioDeEndereco.Consulte(m => m.Codigo == endereco.Codigo).Any();
        }

        private void ValideEnderecoJaCadastrado()
        {
            if (EnderecoJaCadastrado())
        {
                AdicioneInconsistencia("Já existe Endereço cadastrado com o código {0}.", _objetoValidado.Codigo);
            }
        }

        private void ValideEnderecoNaoCadastrado()
        {
            if (!EnderecoJaCadastrado())
            {
                AdicioneInconsistencia("Endereço com o código {0} não está cadastrado.", _objetoValidado.Codigo);
            }
        }
    }
}
